﻿using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AspNetCore.Cache
{
    /// <summary>
    /// 
    /// </summary>
    public class RedisCacheManager : ICacheManager
    {
        private readonly IRedisConnectionWrapper _connectionWrapper;

        private readonly IDatabase _db;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionWrapper"></param>
        public RedisCacheManager(IRedisConnectionWrapper connectionWrapper)
        {
            _connectionWrapper = connectionWrapper;
            _db = _connectionWrapper.GetDatabase();
        }

        /// <summary>
        /// 清理全部
        /// </summary>
        public void Clear()
        {
            foreach (var endPoint in _connectionWrapper.GetEndPoints())
            {
                var server = _connectionWrapper.GetServer(endPoint);
                var keys = server.Keys(_db.Database);
                _db.KeyDelete(keys.ToArray());
            }
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
           var serializedItem = _db.StringGet(key);

            if (!serializedItem.HasValue)
                return default(T);
            var item = JsonConvert.DeserializeObject<T>(serializedItem);
            if (item == null)
                return default(T);
            return item;
        }

        /// <summary>
        /// 检查缓存是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsSet(string key)
        {
            return _db.KeyExists(key);
        }

        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="key"></param>
        public void Remove(string key)
        {
            _db.KeyDelete(key);
        }

        /// <summary>
        /// 匹配删除多项
        /// </summary>
        /// <param name="pattern"></param>
        public void RemoveByPattern(string pattern)
        {
            foreach(var endPoint in _connectionWrapper.GetEndPoints())
            {
                var server = _connectionWrapper.GetServer(endPoint);
                var keys = server.Keys(_db.Database, $"*{pattern}*");
                _db.KeyDelete(keys.ToArray());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <param name="cacheTime"></param>
        public void Set(string key, object data, int cacheTime)
        {
            if (data == null)
                return;

            var expiresIn = TimeSpan.FromMinutes(cacheTime);

            var serializedItem = JsonConvert.SerializeObject(data);

            _db.StringSet(key, serializedItem, expiresIn);
        }
    }
}
